﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;

namespace DataAccess
{
    /// <summary>
    /// OleDb 数据库操作类。
    /// </summary>
    public class OleDbHelper
    {
        /// <summary>
        /// OleDb 数据库连接字段。
        /// </summary>
        private OleDbConnection conn;

        /// <summary>
        /// 获取或设置 OleDb 的连接字符串。
        /// </summary>
        public string ConnectionString
        {
            get { return conn.ConnectionString; }
            set
            {
                if (conn != null)
                {
                    // 当数据库处于连接状态时，关闭数据库。
                    if (conn.State == ConnectionState.Open) conn.Close();
                    conn.Dispose();
                }
                // 初始化数据库连接。
                conn = new OleDbConnection(value.Trim());
            }
        }

        /// <summary>
        /// 测试数据库是否可以连接，并返回测试结果。
        /// </summary>
        /// <returns>测试结果</returns>
        public bool TestConnection()
        {
            bool flag = false;
            try
            {
                // 打开数据库连接。
                conn.Open();
                // 设置可连接值为真。
                flag = true;
            }
            catch { }
            finally
            {
                // 关闭数据库连接。
                if (conn != null) conn.Close();
            }
            return flag;
        }

        /// <summary>
        /// 针对 OleDb 通过一条带参数的SQL语句，并提供参数值，构建一个数据库命令。
        /// </summary>
        /// <param name="sqltext">带参数的SQL语句</param>
        /// <param name="values">参数值</param>
        /// <returns>数据库命令</returns>
        public OleDbCommand CreateCommand(string sqltext, params object[] values)
        {
            return CreateCommand(conn, sqltext, values);
        }

        /// <summary>
        /// 针对 OleDb 通过一条带参数的SQL语句，并提供参数值，给定指定连接构建一个数据库命令。
        /// </summary>
        /// <param name="conn">提供的数据库连接</param>
        /// <param name="sqltext">带参数的SQL语句</param>
        /// <param name="values">参数值</param>
        /// <returns>数据库命令</returns>
        public OleDbCommand CreateCommand(OleDbConnection conn, string sqltext, params object[] values)
        {
            OleDbCommand cmd = new OleDbCommand(sqltext, conn);
            // 按情况分割字符串。
            string[] splitText = sqltext.Split(',', ';', ' ', '=', '(', ')', '\t');
            List<string> paramText = new List<string>();// 参数字符串数组
            foreach (var item in splitText)
            {
                if (item.StartsWith("@"))
                {
                    paramText.Add(item);
                }
            }
            for (int i = 0; i < paramText.Count; i++)
            {
                cmd.Parameters.Add(new OleDbParameter(paramText[i], values[i]));
            }
            return cmd;
        }

        /// <summary>
        /// 针对 OleDb 执行一条完整的SQL语句，并返回受影响的行数。
        /// </summary>
        /// <param name="sqltext">完整的SQL语句</param>
        /// <returns>受影响的行数</returns>
        public int ExecuteNonQuery(string sqltext)
        {
            return ExecuteNonQuery(sqltext, null);
        }

        /// <summary>
        /// 针对 OleDb 执行一条带参数的SQL语句，并提供参数值，并返回受影响的行数。
        /// </summary>
        /// <param name="sqltext">带参数的SQL语句</param>
        /// <param name="values">参数值</param>
        /// <returns>受影响的行数</returns>
        public int ExecuteNonQuery(string sqltext, params object[] values)
        {
            int rows = 0;
            try
            {
                // 打开数据库连接。
                conn.Open();
                // 保存受影响的行数。
                rows = CreateCommand(sqltext, values).ExecuteNonQuery();
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                // 关闭数据库连接。
                if (conn != null) conn.Close();
            }
            return rows;
        }

        /// <summary>
        /// 针对 OleDb 执行一条完整的SQL语句，并返回一个数据库读取器。
        /// </summary>
        /// <param name="sqltext">完整的SQL语句</param>
        /// <returns>数据库读取器</returns>
        public OleDbDataReader ExecuteReader(string sqltext)
        {
            return ExecuteReader(sqltext, null);
        }

        /// <summary>
        /// 针对 OleDb 执行一条带参数的SQL语句，并提供参数值，并返回一个数据库读取器。
        /// </summary>
        /// <param name="sqltext">带参数的SQL语句</param>
        /// <param name="values">参数值</param>
        /// <returns>数据库读取器</returns>
        public OleDbDataReader ExecuteReader(string sqltext, params object[] values)
        {
            // 准备数据库读取对象和新的数据库连接。
            OleDbDataReader rdr = null;
            OleDbConnection new_con = null;
            try
            {
                // 实例化新的数据库连接。
                new_con = new OleDbConnection(conn.ConnectionString);
                new_con.Open();
                rdr = CreateCommand(new_con, sqltext, values).ExecuteReader();// 返回的数据库读取对象
            }
            catch (Exception)
            {
                if (new_con != null && new_con.State == ConnectionState.Open) new_con.Close();
                throw;
            }
            return rdr;
        }

        /// <summary>
        /// 针对 OleDb 执行一条完整的SQL语句，并将得到的数据填充到数据表。
        /// </summary>
        /// <param name="sqltext">完整的SQL语句</param>
        /// <returns>受影响的行数</returns>
        public DataTable GetDataTable(string sqltext)
        {
            return GetDataTable(sqltext, null);
        }

        /// <summary>
        /// 针对 OleDb 执行一条带参数的SQL语句，并提供参数值，并将得到的数据填充到数据表。
        /// </summary>
        /// <param name="sqltext">带参数的SQL语句</param>
        /// <param name="values">参数值</param>
        /// <returns>受影响的行数</returns>
        public DataTable GetDataTable(string sqltext, params object[] values)
        {
            DataTable dtb = new DataTable();
            var cmd = CreateCommand(sqltext, values);
            try
            {
                new OleDbDataAdapter(cmd).Fill(dtb);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (conn != null && cmd.Connection.State == ConnectionState.Open) cmd.Connection.Close();
            }
            return dtb;
        }

        /// <summary>
        /// 针对 OleDb 执行一条完整的SQL语句，得到数据集中首位置的值。
        /// </summary>
        /// <param name="sqltext">完整的SQL语句</param>
        /// <returns>数据集中首位置的值</returns>
        public object ExecuteScalar(string sqltext)
        {
            return ExecuteScalar(sqltext, null);
        }

        /// <summary>
        /// 针对 OleDb 执行一条带参数的SQL语句，并提供参数值，得到数据集中首位置的值。
        /// </summary>
        /// <param name="sqltext">带参数的SQL语句</param>
        /// <param name="values">参数值</param>
        /// <returns>数据集中首位置的值</returns>
        public object ExecuteScalar(string sqltext, params object[] values)
        {
            object obj = null;
            try
            {
                conn.Open();
                obj = CreateCommand(sqltext, values).ExecuteScalar();// 返回的第一行第一列
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (conn != null) conn.Close();
            }
            return obj;
        }
    }
}
